import 'dart:async';
import 'dart:io';

import 'package:http/http.dart' as http;

typedef Process = void Function(int c, int t);

class ContinueDownloader {
  http.Client? _client;
  int _totalBytes = 0;
  int _receivedBytes = 0;

  StreamSubscription<List<int>>? _downloadSubscription;
  Future<void> startDownload(
      {required String url,
      required String savePath,
      required Process process}) async {
    final file = File(savePath);
    if (file.existsSync()) {
      _receivedBytes = await file.length();
    }
    _client = http.Client();
    final request = http.Request('GET', Uri.parse(url))
      ..headers.addAll({'Range': 'bytes=$_receivedBytes-'});
    final response = await _client?.send(request);

    final contentRange = response?.headers['content-length'];
    if (contentRange != null) {
      _totalBytes = int.parse(contentRange);
    }
    _downloadSubscription = response?.stream.listen(
        (List<int> chunk) async {
          _receivedBytes += chunk.length;
          await file.writeAsBytes(chunk,
              mode: file.existsSync() ? FileMode.append : FileMode.write);
          process.call(_receivedBytes, _totalBytes);
        },
        cancelOnError: true,
        onDone: () {
          _client?.close();
        },
        onError: (e) {
          throw Exception('下载失败');
        });
  }

  void close() {
    _downloadSubscription?.cancel();
    _client?.close();
  }
}
